package com.xixi.core.rpc.serializer;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * @author: zxh
 * @date: 2024/8/21 22:26
 * @description: Kryo序列化器
 */
public class CustomKryoSerializer implements CustomSerializer{

	// Kryo序列器线程不安全，使用ThreadLocal保证每个线程只有一个Kryo
	private static final ThreadLocal<Kryo> KRYO_THREAD_LOCAL = ThreadLocal.withInitial(() -> {
		Kryo kryo = new Kryo();
		// 设置动态序列化和反序列化，不提前注册所有类
		kryo.setRegistrationRequired(false);
		return kryo;
	});

	@Override
	public <T> byte[] serialize(T object) throws IOException {
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		Output output = new Output(outputStream);
		KRYO_THREAD_LOCAL.get().writeObject(output, object);
		output.close();
		KRYO_THREAD_LOCAL.remove();
		return outputStream.toByteArray();
	}

	@Override
	public <T> T deserialize(byte[] bytes, Class<T> type) throws IOException {
		ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
		Input input = new Input(inputStream);
		T result = KRYO_THREAD_LOCAL.get().readObject(input, type);
		input.close();
		KRYO_THREAD_LOCAL.remove();
		return result;
	}
}
